//
//  PSNode.h
//  PrefCore
//
//  Created by Sergey on 5/12/14.
//  Copyright (c) 2014 Play-on-smart. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "PSHashSet.h"
#import "PSLinkedList.h"
#import "PSObjectPool.h"
#import "PSGame.h"
#import "PSTreeLevel.h"

@interface PSNode : NSObject <PSListEntry>

+(PSObjectPool*)pool;

// Set of identical nodes
+(PSHashSet*)set;

/// Child positions at round + 1
@property (nonatomic, readonly) PSLinkedList *children;

/// Duplicate hashset's bucket index
@property (nonatomic, readwrite) uint32_t bucketIndex;

@property (nonatomic, readwrite) PSNode *previousInHashset;

@property (nonatomic, readwrite) PSNode *nextInHashset;

/// The number of references from parent upper level nodes
@property (nonatomic, readwrite) uint16_t parents;

@property (nonatomic, readwrite) PSNode *next;

@property (nonatomic, readwrite) PSNode *previous;

@property (nonatomic, readwrite) uint16_t propagated;

/// The winner
@property (nonatomic, readwrite) PSPlayerId winner;

/// The next player
@property (nonatomic, readwrite) PSPlayerId  player;

/// Hands
@property (nonatomic, readonly) PSHandHash *hands;

// Search key for identical leafs
+(PSNode*)keyForPlayer:(PSPlayerId)player andHands:(PSHandHash*)hands;

/// Create a new root node
+(instancetype)nodeWithLevel:(PSTreeLevel*)level
                     starter:(PSPlayerId)starter
                       hand0:(PSHandHash)hand0
                       hand1:(PSHandHash)hand1
                       hand2:(PSHandHash)hand2;

/// Create a new child position
+(instancetype)nodeWithLevel:(PSTreeLevel*)level
                      parent:(PSNode*)parent
                       hands:(PSHandHash*)hands
                      player:(PSPlayerId)player
                      winner:(PSPlayerId)winner
                       card0:(PSCard*)c0
                       card1:(PSCard*)c1
                       card2:(PSCard*)c2;

// IMPORTANT: There is no parent link, so this method does not update
// any information in existing parent nodes.
-(void)destroy;

-(NSString*)description;

-(NSUInteger)hash;

-(BOOL)isEqual:(id)object;

@end
